import numpy as np
import pandas as pd
from typing import Dict, Tuple, Optional
import os

from process.feature_process import *
from process.data_preprocess import *
from process.read_excel import read_data
from utils.evaluation import run_benchmark_evaluation, print_benchmark_results, analyze_benchmark_results, select_best_method
from config import Config

def find_best_method(df: pd.DataFrame, n_trials: int = 100) -> Tuple[str, str, float]:
    """找到最佳方法组合
    
    Returns:
        Tuple[str, str, float]: (预处理方法名, 特征工程方法名, 平均得分)
    """
    # 随机种子
    np.random.seed(1)
    random_states = np.random.randint(1, 1000, size=n_trials)
    
    preprocess_methods = {
        'pre_replace': pre_replace.process,
        'del_iqr': del_iqr.process,
        'del_zscore': del_zscore.process,
        'interpolate': interpolate.process,
        'mean': mean.process,
        'median': median.process
    }
    
    feature_methods = {
        'ymsplit': ymsplit.prepare_features,
        'continus_month': continuous_month.prepare_features,
        'seasonal': seasonal.prepare_features,
        'sliding_window': sliding_window.prepare_features,
        'combined': combined.prepare_features,
        'seasonal_plus': seasonal_plus.prepare_features
    }
    
    all_results = {}
    for pre_name, pre_method in preprocess_methods.items():
        processed_df = pre_method(df.copy())
        if processed_df is None:
            continue
            
        for feat_name, feat_method in feature_methods.items():
            method_name = f"{pre_name}_{feat_name}"
            print(f"\n测试组合: {method_name}")
            try:
                scores = run_benchmark_evaluation(processed_df, feat_method, random_states)
                all_results[method_name] = scores
            except Exception as e:
                print(f"组合测试失败: {str(e)}")
                continue
    
    # 打印详细结果并获取最佳方法
    if all_results:
        print_benchmark_results(all_results, n_trials)
        analyzed_results = analyze_benchmark_results(all_results, n_trials)
        best_method_name, best_result = select_best_method(analyzed_results)
        # 方法名的提取
        for pre_name in preprocess_methods.keys():
            for feat_name in feature_methods.keys():
                if best_method_name == f"{pre_name}_{feat_name}":
                    return pre_name, feat_name, best_result.mean_score
                    
    return None, None, -float('inf')

def main(n_trials: int = 100, excel_path: Optional[str] = None) -> None:
    '''基准测试主函数'''
    if excel_path is None:
        config = Config()
        wd = os.path.dirname(os.path.abspath(__file__))
        excel_path = os.path.join(wd, config.config['data_path'])
        
    df = read_data(excel_path, is_new_format=True)
    print(df)
    if df is None:
        return
        
    best_preprocess, best_feature, best_score = find_best_method(df, n_trials)
    if best_preprocess and best_feature:
        print(f"\n最佳组合方法:")
        print(f"预处理: {best_preprocess}")
        print(f"特征工程: {best_feature}")
        print(f"最高得分: {best_score:.4f}")
    else:
        print("\n未找到有效的组合方法")

if __name__ == '__main__':
    main(n_trials=100)